package com.ivr.cm.handler.validate.impl;

import java.text.SimpleDateFormat;
import java.util.AbstractMap;
import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;

import com.ivr.cm.cache.Cacheable;
import com.ivr.cm.dao.ILimitBusinessDao;
import com.ivr.cm.data.ValidateData;
import com.ivr.cm.handler.validate.ValidateServiceIF;
import com.ivr.cm.service.StateCode;
import com.ivr.cm.vo.LimitBusinessVo;

/**
 * 业务总量 鉴权
 * @author liugeng
 * @date 2015-12-15
 *
 */
public class ValidateLimitBusinessImpl implements ValidateServiceIF {
	private static Logger logger = Logger.getLogger(ValidateLimitBusinessImpl.class);
	
	private Cacheable limitBusinessCache;
	private ILimitBusinessDao limitBusinessDao;
	
	@Override
	public int doProcess(ValidateData validateData) {
		/**获得主叫号码*/
		String mobile = validateData.getBaseData().getCalling();
		/**获得业务号码长号码*/
		String sp_number = validateData.getBaseData().getLong_called();
		logger.info(String.format("[%s][%s][业务总量限制鉴权]开始", mobile, sp_number));
		
		AbstractMap<String, List<LimitBusinessVo>> limitBusinessMap = (AbstractMap<String, List<LimitBusinessVo>>) limitBusinessCache.getCache();
		
		boolean flag = false;
		if(limitBusinessMap != null && limitBusinessMap.size() > 0){
			/**根据业务长号码获得对应的渠道信息*/
			int lower_id = limitBusinessDao.getLowerIdBySpNumber(sp_number);
			if(lower_id != 0){
				List<LimitBusinessVo> limitBusinessVoList = limitBusinessMap.get(String.valueOf(lower_id));
				
				if(limitBusinessVoList != null && limitBusinessVoList.size() > 0){
					boolean isExists = false;
					for(LimitBusinessVo limitBusinessVo : limitBusinessVoList){
						if("".equals(limitBusinessVo.getProvince()) || validateData.getBaseData().getProvince().equals(limitBusinessVo.getProvince())){
							isExists = true;
							/**格式化业务总量限制的当天和当月*/
							Date nowDate = new Date();
							SimpleDateFormat formatDay = new SimpleDateFormat("yyyy-MM-dd");
							String day_time = formatDay.format(nowDate);
							SimpleDateFormat formatMonth = new SimpleDateFormat("yyyy-MM");
							String month_time = formatMonth.format(nowDate);
							
							/**根据渠道ID和省份获得渠道在当前省份当日已经拨打金额*/
							int lowerused_day = limitBusinessDao.getLowerUsedDay(lower_id, validateData.getBaseData().getProvince(), day_time);
							if(lowerused_day >= limitBusinessVo.getDay_limit()){
								logger.info(String.format("[%s][%s][业务总量限制鉴权]未通过,渠道[lower_id=%d], 配置省[%s], 日限金额[%d] 当天已用金额[%d]", mobile, sp_number, lower_id, limitBusinessVo.getProvince(), limitBusinessVo.getDay_limit(), lowerused_day));
								flag = true;
								break;
							}
							
							/**根据渠道ID和省份获得渠道在当前省份当月已经拨打金额*/
							int lowerused_month = limitBusinessDao.getLowerUsedMonth(lower_id, validateData.getBaseData().getProvince(), month_time);
							if(lowerused_month >= limitBusinessVo.getMonth_limit()){
								logger.info(String.format("[%s][%s][业务总量限制鉴权]未通过,渠道[lower_id=%d], 配置省[%s], 月限金额[%d] 当月已用金额[%d]", mobile, sp_number, lower_id, limitBusinessVo.getProvince(), limitBusinessVo.getMonth_limit(), lowerused_month));
								flag = true;
								break;
							}
							
							logger.info(String.format("[%s][%s][业务总量限制鉴权]通过,渠道[lower_id=%d], 配置省[%s], 日限金额[%d], 月限金额[%d], 当天已用金额[%d], 当月已用金额[%d]", mobile, sp_number, lower_id, validateData.getBaseData().getProvince(),limitBusinessVo.getDay_limit(),limitBusinessVo.getMonth_limit(),lowerused_day,lowerused_month));
							
						}
					}
					
					if(!isExists){
						logger.info(String.format("[%s][%s][业务总量限制鉴权]通过,渠道[lower_id=%d]无[%s]省份限制", mobile, sp_number, lower_id, validateData.getBaseData().getProvince()));
					}
				}else{
					logger.info(String.format("[%s][%s][业务总量限制鉴权]通过,渠道[lower_id=%d]无业务限制配置信息", mobile, sp_number, lower_id));
				}
			}else{
				logger.info(String.format("[%s][%s][业务总量限制鉴权]通过,无路由配置信息", mobile, sp_number));
			}
		}else{
			logger.info(String.format("[%s][%s]渠道[业务总量限制鉴权]通过,无业务限制配置信息", mobile, sp_number));
		}
		
		if(flag){
			validateData.setResult(ValidateData.RESULT_INVALID_NOTIMELEFT);
			validateData.setVoice(ValidateData.VOICE_INVALID_NOTIMELEFT);
			validateData.setTimeRemain(0);
			validateData.setStatecode(StateCode.CONFIG_LIMIT);
			return ValidateChain.VALIDATE_FINISHED;
		}
		
		return ValidateChain.VALIDATE_CONTINUE;
	}

	public Cacheable getLimitBusinessCache() {
		return limitBusinessCache;
	}
	public void setLimitBusinessCache(Cacheable limitBusinessCache) {
		this.limitBusinessCache = limitBusinessCache;
	}
	public ILimitBusinessDao getLimitBusinessDao() {
		return limitBusinessDao;
	}
	public void setLimitBusinessDao(ILimitBusinessDao limitBusinessDao) {
		this.limitBusinessDao = limitBusinessDao;
	}
}